Handle asyncio.CancelledError in ToolNode #6764
Open
+78
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #6726 - ToolNode now properly handles asyncio.CancelledError when handle_tool_errors=True.
Problem
When a tool execution is cancelled via
asyncio.CancelledError, theToolNodedoes not create an errorToolMessageeven whenhandle_tool_errors=True. This leaves the message history in an invalid state where anAIMessagehastool_callswithout correspondingToolMessages, causing INVALID_CHAT_HISTORY errors on subsequent LLM calls.Root cause:
asyncio.CancelledErrorinherits fromBaseException, notException, so it bypasses the existing exception handler which only catchesExceptionand its subclasses.Solution
Added an explicit handler for
asyncio.CancelledErrorin_execute_tool_async()that:CancelledErrorbefore the generalExceptionhandlerhandle_tool_errors=True, converts it to an errorToolMessagewith "Tool execution was cancelled" messagehandle_tool_errors=False, re-raises theCancelledError(preserving existing behavior)Test Plan
Added two comprehensive tests:
test_tool_node_handles_cancelled_error: Verifies that when a tool raises CancelledError and handle_tool_errors=True, it returns an error ToolMessage instead of propagating the errortest_tool_node_raises_cancelled_error_when_not_handled: Verifies that when handle_tool_errors=False, CancelledError is still raisedChanges
libs/prebuilt/langgraph/prebuilt/tool_node.py: Added CancelledError handlerlibs/prebuilt/tests/test_tool_node.py: Added regression tests